"""
摄像头相关的Pydantic模式

本模块定义了摄像头管理系统中所有的数据模式，包括：
- 基础数据模式（创建、更新、响应）
- 查询和筛选模式
- 批量操作模式
- 健康检查和统计模式
- 枚举类型定义

所有模式都包含完整的数据验证规则和文档说明。

Task 5.2 增强功能：
- 字段长度和格式验证
- 坐标范围验证器
- 枚举类型验证
- 自定义业务规则验证器
"""
from pydantic import BaseModel, Field, field_validator, model_validator, ConfigDict
from typing import Optional, List, Any, Dict, Union
from datetime import datetime
from enum import Enum
import re
from .validators import CameraValidators, BusinessRuleValidators, ValidationError


class CameraStatus(str, Enum):
    """摄像头状态枚举"""
    ONLINE = "online"
    OFFLINE = "offline"
    ERROR = "error"
    MAINTENANCE = "maintenance"


class StreamStatus(str, Enum):
    """流状态枚举"""
    INACTIVE = "inactive"
    ACTIVE = "active"
    ERROR = "error"
    RECONNECTING = "reconnecting"


class CameraBase(BaseModel):
    """
    摄像头基础模式
    
    包含摄像头的所有基础字段和验证规则。
    用作其他摄像头相关模式的基类。
    """
    model_config = ConfigDict(
        str_strip_whitespace=True,  # 自动去除字符串前后空格
        validate_assignment=True,   # 赋值时也进行验证
        use_enum_values=True,      # 使用枚举值而不是枚举对象
        extra='forbid'             # 禁止额外字段
    )
    
    name: str = Field(
        ..., 
        min_length=1, 
        max_length=255, 
        description="设备名称，必须唯一",
        examples=["教学楼A-101摄像头", "图书馆入口监控"]
    )
    longitude: float = Field(
        ..., 
        ge=-180, 
        le=180, 
        description="经度坐标，范围 -180 到 180",
        examples=[116.397128, -74.005974]
    )
    latitude: float = Field(
        ..., 
        ge=-90, 
        le=90, 
        description="纬度坐标，范围 -90 到 90",
        examples=[39.916527, 40.712776]
    )
    height: Optional[float] = Field(
        default=10.0, 
        ge=0, 
        le=1000,
        description="安装高度（米），默认10米",
        examples=[3.5, 10.0, 25.0]
    )
    location: Optional[str] = Field(
        default=None, 
        max_length=255, 
        description="安装位置描述",
        examples=["教学楼A栋1楼大厅", "图书馆主入口", "操场东南角"]
    )
    rtsp_url: Optional[str] = Field(
        default=None, 
        max_length=512, 
        description="RTSP流地址，必须以rtsp://开头",
        examples=["rtsp://192.168.1.100:554/stream1", "rtsp://camera.example.com/live"]
    )
    wvp_device_id: Optional[str] = Field(
        default=None, 
        max_length=100, 
        description="WVP-Pro设备ID",
        examples=["34020000001320000001", "device_001"]
    )
    wvp_channel_id: Optional[str] = Field(
        default=None, 
        max_length=100, 
        description="WVP-Pro通道ID",
        examples=["34020000001320000001", "channel_001"]
    )
    description: Optional[str] = Field(
        default=None, 
        max_length=1000,
        description="设备详细描述",
        examples=["高清网络摄像头，支持夜视功能", "4K分辨率，具备人脸识别能力"]
    )
    ai_enabled: bool = Field(
        default=False, 
        description="是否启用AI分析功能"
    )
    
    # 实时流处理相关字段
    ai_algorithms: Optional[Dict[str, Any]] = Field(
        default=None, 
        description="启用的AI算法配置，键为算法名称，值为配置参数",
        examples=[
            {"face_detection": {"confidence": 0.8}, "object_detection": {"classes": ["person", "vehicle"]}}
        ]
    )
    processing_fps: int = Field(
        default=3, 
        ge=1, 
        le=30, 
        description="AI处理帧率，每秒处理帧数"
    )
    priority_level: int = Field(
        default=5, 
        ge=1, 
        le=10, 
        description="处理优先级，1最低，10最高"
    )

    @field_validator('rtsp_url')
    @classmethod
    def validate_rtsp_url(cls, v: Optional[str]) -> Optional[str]:
        """验证RTSP URL格式 - 使用增强验证器"""
        if v is None:
            return v
        try:
            return CameraValidators.validate_rtsp_url(v)
        except ValidationError as e:
            raise ValueError(e.message)
    
    @field_validator('name')
    @classmethod
    def validate_name(cls, v: str) -> str:
        """验证设备名称 - 使用增强验证器"""
        try:
            return CameraValidators.validate_device_name(v)
        except ValidationError as e:
            raise ValueError(e.message)
    
    @field_validator('location')
    @classmethod
    def validate_location(cls, v: Optional[str]) -> Optional[str]:
        """验证位置描述"""
        if v is None:
            return v
        
        v = v.strip()
        if not v:
            return None
        
        if len(v) > 255:
            raise ValueError('位置描述长度不能超过255字符')
        
        return v
    
    @field_validator('height')
    @classmethod
    def validate_height(cls, v: Optional[float]) -> Optional[float]:
        """验证安装高度 - 使用增强验证器"""
        if v is None:
            return v
        try:
            return CameraValidators.validate_height(v)
        except ValidationError as e:
            raise ValueError(e.message)
    
    @field_validator('ai_algorithms')
    @classmethod
    def validate_ai_algorithms(cls, v: Optional[Dict[str, Any]]) -> Optional[Dict[str, Any]]:
        """验证AI算法配置 - 使用增强验证器"""
        if v is None:
            return v
        try:
            return CameraValidators.validate_ai_algorithms(v)
        except ValidationError as e:
            raise ValueError(e.message)
    
    @field_validator('wvp_device_id')
    @classmethod
    def validate_wvp_device_id(cls, v: Optional[str]) -> Optional[str]:
        """验证WVP设备ID - 使用增强验证器"""
        if v is None:
            return v
        try:
            return CameraValidators.validate_wvp_device_id(v)
        except ValidationError as e:
            raise ValueError(e.message)
    
    @field_validator('wvp_channel_id')
    @classmethod
    def validate_wvp_channel_id(cls, v: Optional[str]) -> Optional[str]:
        """验证WVP通道ID - 使用增强验证器"""
        if v is None:
            return v
        try:
            return CameraValidators.validate_wvp_device_id(v)  # 使用相同的验证规则
        except ValidationError as e:
            raise ValueError(e.message)
    
    @field_validator('description')
    @classmethod
    def validate_description(cls, v: Optional[str]) -> Optional[str]:
        """验证描述信息 - 使用增强验证器"""
        if v is None:
            return v
        try:
            return CameraValidators.validate_description(v)
        except ValidationError as e:
            raise ValueError(e.message)
    
    @field_validator('processing_fps')
    @classmethod
    def validate_processing_fps(cls, v: int) -> int:
        """验证处理帧率 - 使用增强验证器"""
        try:
            return CameraValidators.validate_processing_fps(v)
        except ValidationError as e:
            raise ValueError(e.message)
    
    @field_validator('priority_level')
    @classmethod
    def validate_priority_level(cls, v: int) -> int:
        """验证优先级 - 使用增强验证器"""
        try:
            return CameraValidators.validate_priority_level(v)
        except ValidationError as e:
            raise ValueError(e.message)
    
    @model_validator(mode='after')
    def validate_coordinates_and_business_rules(self) -> 'CameraBase':
        """验证坐标和业务规则 - 使用增强验证器"""
        # 坐标验证
        if hasattr(self, 'longitude') and hasattr(self, 'latitude'):
            try:
                CameraValidators.validate_coordinates(self.longitude, self.latitude)
            except ValidationError as e:
                raise ValueError(e.message)
            
            # 检查是否在中国境内（警告级别）
            if not CameraValidators.validate_china_coordinates(self.longitude, self.latitude):
                # 这里可以记录警告日志，但不阻止保存
                # logger.warning(f"摄像头坐标不在中国境内: ({self.longitude}, {self.latitude})")
                pass
        
        # AI算法与设备能力兼容性检查
        if hasattr(self, 'ai_enabled') and self.ai_enabled and hasattr(self, 'ai_algorithms'):
            if self.ai_algorithms:
                try:
                    BusinessRuleValidators.validate_ai_algorithm_compatibility(
                        self.ai_algorithms, 
                        None  # 设备能力信息需要从数据库获取
                    )
                except ValidationError as e:
                    # 这里只记录警告，不阻止保存
                    pass
        
        return self


class CameraCreate(CameraBase):
    """
    创建摄像头请求模式
    
    用于验证创建摄像头的请求数据。
    继承自CameraBase，包含所有必需的字段验证。
    
    示例:
    {
        "name": "教学楼A-101摄像头",
        "longitude": 116.397128,
        "latitude": 39.916527,
        "location": "教学楼A栋1楼大厅",
        "rtsp_url": "rtsp://192.168.1.100:554/stream1",
        "ai_enabled": true
    }
    """
    
    @model_validator(mode='after')
    def validate_create_data(self) -> 'CameraCreate':
        """创建时的额外验证"""
        # 如果启用了AI，建议提供RTSP URL
        if self.ai_enabled and not self.rtsp_url:
            # 这里只是警告，不阻止创建
            pass
        
        return self


class CameraUpdate(BaseModel):
    """
    更新摄像头请求模式
    
    用于验证更新摄像头的请求数据。
    所有字段都是可选的，只更新提供的字段。
    
    示例:
    {
        "name": "新的摄像头名称",
        "location": "新的安装位置",
        "ai_enabled": true,
        "status": "online"
    }
    """
    model_config = ConfigDict(
        str_strip_whitespace=True,
        validate_assignment=True,
        use_enum_values=True,
        extra='forbid'
    )
    
    name: Optional[str] = Field(
        default=None, 
        min_length=1, 
        max_length=255,
        description="设备名称",
        examples=["新的摄像头名称"]
    )
    longitude: Optional[float] = Field(
        default=None, 
        ge=-180, 
        le=180,
        description="经度坐标"
    )
    latitude: Optional[float] = Field(
        default=None, 
        ge=-90, 
        le=90,
        description="纬度坐标"
    )
    height: Optional[float] = Field(
        default=None, 
        ge=0, 
        le=1000,
        description="安装高度（米）"
    )
    location: Optional[str] = Field(
        default=None, 
        max_length=255,
        description="安装位置描述"
    )
    rtsp_url: Optional[str] = Field(
        default=None, 
        max_length=512,
        description="RTSP流地址"
    )
    wvp_device_id: Optional[str] = Field(
        default=None, 
        max_length=100,
        description="WVP-Pro设备ID"
    )
    wvp_channel_id: Optional[str] = Field(
        default=None, 
        max_length=100,
        description="WVP-Pro通道ID"
    )
    description: Optional[str] = Field(
        default=None, 
        max_length=1000,
        description="设备详细描述"
    )
    ai_enabled: Optional[bool] = Field(
        default=None,
        description="是否启用AI分析功能"
    )
    status: Optional[CameraStatus] = Field(
        default=None,
        description="摄像头状态"
    )
    
    # 实时流处理相关字段
    ai_algorithms: Optional[Dict[str, Any]] = Field(
        default=None,
        description="启用的AI算法配置"
    )
    processing_fps: Optional[int] = Field(
        default=None, 
        ge=1, 
        le=30,
        description="AI处理帧率"
    )
    priority_level: Optional[int] = Field(
        default=None, 
        ge=1, 
        le=10,
        description="处理优先级"
    )

    @field_validator('rtsp_url')
    @classmethod
    def validate_rtsp_url(cls, v: Optional[str]) -> Optional[str]:
        """验证RTSP URL格式 - 使用增强验证器"""
        if v is None:
            return v
        try:
            return CameraValidators.validate_rtsp_url(v)
        except ValidationError as e:
            raise ValueError(e.message)
    
    @field_validator('name')
    @classmethod
    def validate_name(cls, v: Optional[str]) -> Optional[str]:
        """验证设备名称 - 使用增强验证器"""
        if v is None:
            return v
        try:
            return CameraValidators.validate_device_name(v)
        except ValidationError as e:
            raise ValueError(e.message)
    
    @field_validator('height')
    @classmethod
    def validate_height(cls, v: Optional[float]) -> Optional[float]:
        """验证安装高度 - 使用增强验证器"""
        if v is None:
            return v
        try:
            return CameraValidators.validate_height(v)
        except ValidationError as e:
            raise ValueError(e.message)
    
    @field_validator('location')
    @classmethod
    def validate_location(cls, v: Optional[str]) -> Optional[str]:
        """验证位置描述"""
        if v is None:
            return v
        
        v = v.strip()
        if not v:
            return None
        
        if len(v) > 255:
            raise ValueError('位置描述长度不能超过255字符')
        
        return v
    
    @field_validator('wvp_device_id')
    @classmethod
    def validate_wvp_device_id(cls, v: Optional[str]) -> Optional[str]:
        """验证WVP设备ID - 使用增强验证器"""
        if v is None:
            return v
        try:
            return CameraValidators.validate_wvp_device_id(v)
        except ValidationError as e:
            raise ValueError(e.message)
    
    @field_validator('wvp_channel_id')
    @classmethod
    def validate_wvp_channel_id(cls, v: Optional[str]) -> Optional[str]:
        """验证WVP通道ID - 使用增强验证器"""
        if v is None:
            return v
        try:
            return CameraValidators.validate_wvp_device_id(v)
        except ValidationError as e:
            raise ValueError(e.message)
    
    @field_validator('description')
    @classmethod
    def validate_description(cls, v: Optional[str]) -> Optional[str]:
        """验证描述信息 - 使用增强验证器"""
        if v is None:
            return v
        try:
            return CameraValidators.validate_description(v)
        except ValidationError as e:
            raise ValueError(e.message)
    
    @field_validator('ai_algorithms')
    @classmethod
    def validate_ai_algorithms(cls, v: Optional[Dict[str, Any]]) -> Optional[Dict[str, Any]]:
        """验证AI算法配置 - 使用增强验证器"""
        if v is None:
            return v
        try:
            return CameraValidators.validate_ai_algorithms(v)
        except ValidationError as e:
            raise ValueError(e.message)
    
    @field_validator('processing_fps')
    @classmethod
    def validate_processing_fps(cls, v: Optional[int]) -> Optional[int]:
        """验证处理帧率 - 使用增强验证器"""
        if v is None:
            return v
        try:
            return CameraValidators.validate_processing_fps(v)
        except ValidationError as e:
            raise ValueError(e.message)
    
    @field_validator('priority_level')
    @classmethod
    def validate_priority_level(cls, v: Optional[int]) -> Optional[int]:
        """验证优先级 - 使用增强验证器"""
        if v is None:
            return v
        try:
            return CameraValidators.validate_priority_level(v)
        except ValidationError as e:
            raise ValueError(e.message)
    
    @field_validator('status')
    @classmethod
    def validate_status(cls, v: Optional[CameraStatus]) -> Optional[CameraStatus]:
        """验证状态枚举"""
        if v is None:
            return v
        
        # Pydantic会自动验证枚举类型
        # 这里可以添加额外的业务规则验证
        return v
    
    @model_validator(mode='after')
    def validate_update_consistency_and_business_rules(self) -> 'CameraUpdate':
        """验证更新数据的一致性和业务规则"""
        # 坐标一致性验证
        if self.longitude is not None and self.latitude is not None:
            try:
                CameraValidators.validate_coordinates(self.longitude, self.latitude)
            except ValidationError as e:
                raise ValueError(e.message)
        
        # 状态转换验证（需要当前状态信息，在服务层处理）
        # if self.status is not None:
        #     # 这里需要当前状态信息，在服务层进行验证
        #     pass
        
        # AI配置一致性检查
        if self.ai_enabled is True and self.ai_algorithms is None:
            # 这里只是提示，不阻止更新
            # 可以在服务层记录警告日志
            pass
        elif self.ai_enabled is False and self.ai_algorithms is not None:
            # 禁用AI但提供了算法配置，给出警告
            pass
        
        return self


class CameraResponse(CameraBase):
    """
    摄像头响应模式
    
    用于API响应的摄像头数据格式。
    包含所有摄像头信息以及运行时状态数据。
    
    示例:
    {
        "id": 1,
        "name": "教学楼A-101摄像头",
        "longitude": 116.397128,
        "latitude": 39.916527,
        "status": "online",
        "stream_status": "active",
        "ai_enabled": true,
        "created_at": "2024-01-01T00:00:00Z",
        "updated_at": "2024-01-01T12:00:00Z"
    }
    """
    model_config = ConfigDict(from_attributes=True)
    
    id: int = Field(
        ...,
        description="摄像头唯一标识符",
        examples=[1, 42, 1001]
    )
    status: CameraStatus = Field(
        ...,
        description="摄像头当前状态"
    )
    stream_status: StreamStatus = Field(
        default=StreamStatus.INACTIVE,
        description="视频流状态"
    )
    stream_url: Optional[str] = Field(
        default=None,
        description="当前可用的流地址（如HLS、WebRTC等）",
        examples=["http://localhost:8080/hls/camera_1.m3u8"]
    )
    last_frame_time: Optional[datetime] = Field(
        default=None,
        description="最后一帧的时间戳"
    )
    performance_metrics: Optional[Dict[str, Any]] = Field(
        default=None,
        description="性能指标数据",
        examples=[{
            "fps": 25.5,
            "bitrate": 2048,
            "latency_ms": 150,
            "packet_loss": 0.01
        }]
    )
    reconnect_count: int = Field(
        default=0,
        ge=0,
        description="重连次数统计"
    )
    last_error: Optional[str] = Field(
        default=None,
        max_length=500,
        description="最后一次错误信息"
    )
    created_at: datetime = Field(
        ...,
        description="创建时间"
    )
    updated_at: datetime = Field(
        ...,
        description="最后更新时间"
    )
    
    # 计算属性
    @property
    def is_online(self) -> bool:
        """是否在线"""
        return self.status == CameraStatus.ONLINE
    
    @property
    def is_streaming(self) -> bool:
        """是否正在推流"""
        return self.stream_status == StreamStatus.ACTIVE
    
    @property
    def health_score(self) -> int:
        """健康评分 0-100"""
        score = 100
        
        # 根据状态扣分
        if self.status == CameraStatus.OFFLINE:
            score -= 50
        elif self.status == CameraStatus.ERROR:
            score -= 70
        elif self.status == CameraStatus.MAINTENANCE:
            score -= 20
        
        # 根据重连次数扣分
        if self.reconnect_count > 10:
            score -= 20
        elif self.reconnect_count > 5:
            score -= 10
        
        # 根据流状态扣分
        if self.stream_status == StreamStatus.ERROR:
            score -= 15
        elif self.stream_status == StreamStatus.RECONNECTING:
            score -= 5
        
        return max(0, score)


class CameraListResponse(BaseModel):
    """
    摄像头列表响应模式 - Task 5.3 增强版
    
    支持分页、筛选、排序和搜索的完整响应格式
    """
    items: List[CameraResponse] = Field(..., description="摄像头列表")
    total: int = Field(..., ge=0, description="总记录数")
    page: int = Field(..., ge=1, description="当前页码")
    size: int = Field(..., ge=1, description="每页大小")
    pages: int = Field(..., ge=0, description="总页数")
    
    # 增强的分页信息
    has_previous: bool = Field(..., description="是否有上一页")
    has_next: bool = Field(..., description="是否有下一页")
    previous_page: Optional[int] = Field(None, description="上一页页码")
    next_page: Optional[int] = Field(None, description="下一页页码")
    
    # 筛选和搜索信息
    filters_applied: Dict[str, Any] = Field(default_factory=dict, description="应用的筛选条件")
    search_query: Optional[str] = Field(None, description="搜索查询")
    sort_by: Optional[str] = Field(None, description="排序字段")
    sort_order: Optional[str] = Field(None, description="排序方向")
    
    # 统计信息
    filtered_count: int = Field(..., ge=0, description="筛选后的记录数")
    
    @model_validator(mode='after')
    def validate_pagination_info(self) -> 'CameraListResponse':
        """验证分页信息的一致性"""
        # 计算分页信息
        self.pages = (self.total + self.size - 1) // self.size if self.total > 0 else 0
        self.has_previous = self.page > 1
        self.has_next = self.page < self.pages
        self.previous_page = self.page - 1 if self.has_previous else None
        self.next_page = self.page + 1 if self.has_next else None
        
        return self


class CameraStatusUpdate(BaseModel):
    """摄像头状态更新模式"""
    status: CameraStatus


class CameraConnectionTest(BaseModel):
    """摄像头连接测试结果"""
    success: bool
    message: str
    response_time: Optional[float] = None
    error_code: Optional[str] = None


class SortOrder(str, Enum):
    """排序方向枚举"""
    ASC = "asc"
    DESC = "desc"


class CameraFilters(BaseModel):
    """
    摄像头筛选条件 - Task 5.3 增强版
    
    支持多维度筛选、搜索、排序和分页的完整查询参数
    """
    model_config = ConfigDict(
        str_strip_whitespace=True,
        validate_assignment=True,
        extra='forbid'
    )
    
    # 基础筛选条件
    name: Optional[str] = Field(
        default=None, 
        max_length=255,
        description="设备名称筛选（支持模糊匹配）",
        examples=["教学楼", "摄像头"]
    )
    location: Optional[str] = Field(
        default=None, 
        max_length=255,
        description="位置筛选（支持模糊匹配）",
        examples=["教学楼A", "图书馆"]
    )
    status: Optional[CameraStatus] = Field(
        default=None,
        description="状态筛选"
    )
    ai_enabled: Optional[bool] = Field(
        default=None,
        description="AI启用状态筛选"
    )
    
    # 地理位置筛选
    min_longitude: Optional[float] = Field(
        default=None, 
        ge=-180, 
        le=180,
        description="最小经度"
    )
    max_longitude: Optional[float] = Field(
        default=None, 
        ge=-180, 
        le=180,
        description="最大经度"
    )
    min_latitude: Optional[float] = Field(
        default=None, 
        ge=-90, 
        le=90,
        description="最小纬度"
    )
    max_latitude: Optional[float] = Field(
        default=None, 
        ge=-90, 
        le=90,
        description="最大纬度"
    )
    
    # 高度筛选
    min_height: Optional[float] = Field(
        default=None, 
        ge=0,
        description="最小安装高度"
    )
    max_height: Optional[float] = Field(
        default=None, 
        ge=0,
        description="最大安装高度"
    )
    
    # WVP相关筛选
    wvp_device_id: Optional[str] = Field(
        default=None,
        max_length=100,
        description="WVP设备ID筛选"
    )
    has_rtsp_url: Optional[bool] = Field(
        default=None,
        description="是否有RTSP地址"
    )
    
    # AI算法筛选
    ai_algorithms: Optional[List[str]] = Field(
        default=None,
        description="AI算法筛选（包含任一算法）",
        examples=[["face_detection", "object_detection"]]
    )
    
    # 时间范围筛选
    created_after: Optional[datetime] = Field(
        default=None,
        description="创建时间起始"
    )
    created_before: Optional[datetime] = Field(
        default=None,
        description="创建时间结束"
    )
    updated_after: Optional[datetime] = Field(
        default=None,
        description="更新时间起始"
    )
    updated_before: Optional[datetime] = Field(
        default=None,
        description="更新时间结束"
    )
    
    # 搜索功能
    search: Optional[str] = Field(
        default=None,
        max_length=255,
        description="全文搜索（搜索名称、位置、描述）",
        examples=["教学楼 摄像头"]
    )
    search_fields: Optional[List[str]] = Field(
        default=None,
        description="指定搜索字段",
        examples=[["name", "location", "description"]]
    )
    
    # 排序功能
    sort_by: Optional[str] = Field(
        default="created_at",
        description="排序字段",
        examples=["name", "created_at", "updated_at", "status"]
    )
    sort_order: SortOrder = Field(
        default=SortOrder.DESC,
        description="排序方向"
    )
    
    # 分页参数
    page: int = Field(
        default=1, 
        ge=1,
        description="页码，从1开始"
    )
    size: int = Field(
        default=10, 
        ge=1, 
        le=100,
        description="每页大小，最大100"
    )
    
    # 高级筛选选项
    include_inactive: bool = Field(
        default=True,
        description="是否包含非活跃摄像头"
    )
    only_with_errors: bool = Field(
        default=False,
        description="仅显示有错误的摄像头"
    )
    
    @field_validator('sort_by')
    @classmethod
    def validate_sort_field(cls, v: Optional[str]) -> Optional[str]:
        """验证排序字段"""
        if v is None:
            return v
        
        valid_sort_fields = {
            'id', 'name', 'location', 'status', 'ai_enabled',
            'longitude', 'latitude', 'height', 'created_at', 'updated_at',
            'wvp_device_id', 'processing_fps', 'priority_level'
        }
        
        if v not in valid_sort_fields:
            raise ValueError(f"无效的排序字段：{v}，有效字段：{sorted(valid_sort_fields)}")
        
        return v
    
    @field_validator('search_fields')
    @classmethod
    def validate_search_fields(cls, v: Optional[List[str]]) -> Optional[List[str]]:
        """验证搜索字段"""
        if v is None:
            return v
        
        valid_search_fields = {'name', 'location', 'description', 'wvp_device_id'}
        
        for field in v:
            if field not in valid_search_fields:
                raise ValueError(f"无效的搜索字段：{field}，有效字段：{sorted(valid_search_fields)}")
        
        return v
    
    @field_validator('ai_algorithms')
    @classmethod
    def validate_ai_algorithms_filter(cls, v: Optional[List[str]]) -> Optional[List[str]]:
        """验证AI算法筛选"""
        if v is None:
            return v
        
        from .validators import CameraValidators
        
        for algorithm in v:
            if algorithm not in CameraValidators.SUPPORTED_AI_ALGORITHMS:
                raise ValueError(f"不支持的AI算法：{algorithm}")
        
        return v
    
    @model_validator(mode='after')
    def validate_coordinate_ranges(self) -> 'CameraFilters':
        """验证坐标范围的合理性"""
        # 验证经度范围
        if (self.min_longitude is not None and self.max_longitude is not None and 
            self.min_longitude > self.max_longitude):
            raise ValueError("最小经度不能大于最大经度")
        
        # 验证纬度范围
        if (self.min_latitude is not None and self.max_latitude is not None and 
            self.min_latitude > self.max_latitude):
            raise ValueError("最小纬度不能大于最大纬度")
        
        # 验证高度范围
        if (self.min_height is not None and self.max_height is not None and 
            self.min_height > self.max_height):
            raise ValueError("最小高度不能大于最大高度")
        
        # 验证时间范围
        if (self.created_after is not None and self.created_before is not None and 
            self.created_after > self.created_before):
            raise ValueError("创建开始时间不能晚于结束时间")
        
        if (self.updated_after is not None and self.updated_before is not None and 
            self.updated_after > self.updated_before):
            raise ValueError("更新开始时间不能晚于结束时间")
        
        return self
    
    def to_dict(self, exclude_none: bool = True) -> Dict[str, Any]:
        """转换为字典格式，便于数据库查询"""
        data = self.model_dump(exclude_none=exclude_none)
        
        # 处理枚举值
        if 'status' in data and data['status']:
            data['status'] = data['status'].value if hasattr(data['status'], 'value') else data['status']
        
        if 'sort_order' in data and data['sort_order']:
            data['sort_order'] = data['sort_order'].value if hasattr(data['sort_order'], 'value') else data['sort_order']
        
        return data
    
    def get_coordinate_bounds(self) -> Optional[Dict[str, float]]:
        """获取坐标边界，用于地理查询"""
        if any([self.min_longitude, self.max_longitude, self.min_latitude, self.max_latitude]):
            return {
                'min_longitude': self.min_longitude or -180,
                'max_longitude': self.max_longitude or 180,
                'min_latitude': self.min_latitude or -90,
                'max_latitude': self.max_latitude or 90
            }
        return None


class BatchStatusUpdate(BaseModel):
    """批量状态更新模式"""
    camera_ids: List[int] = Field(..., min_items=1, description="摄像头ID列表")
    status: CameraStatus = Field(..., description="目标状态")
    reason: Optional[str] = Field(None, max_length=255, description="更新原因")


class BatchUpdateRequest(BaseModel):
    """批量更新请求模式"""
    updates: List[Dict[str, Any]] = Field(..., min_items=1, description="更新数据列表")
    validate_all: bool = Field(default=True, description="是否验证所有数据")


class CameraHealthCheck(BaseModel):
    """摄像头健康检查结果"""
    camera_id: int
    name: str
    status: CameraStatus
    connection_status: str
    last_check_time: datetime
    response_time: Optional[float] = None
    error_message: Optional[str] = None
    health_score: int = Field(ge=0, le=100, description="健康评分 0-100")


class SystemHealthSummary(BaseModel):
    """系统健康摘要"""
    total_cameras: int
    online_cameras: int
    offline_cameras: int
    error_cameras: int
    maintenance_cameras: int
    average_health_score: float
    last_check_time: datetime
    critical_issues: List[str] = []
    warnings: List[str] = []


class StatisticsSummary(BaseModel):
    """统计信息摘要"""
    total_cameras: int
    status_distribution: Dict[str, int]
    ai_enabled_count: int
    location_distribution: Dict[str, int]
    recent_additions: int
    performance_metrics: Dict[str, Any]
    health_summary: SystemHealthSummary


# Task 5.2 增强验证模式

class ValidationResult(BaseModel):
    """验证结果模式"""
    valid: bool = Field(..., description="验证是否通过")
    error_count: int = Field(default=0, ge=0, description="错误数量")
    warning_count: int = Field(default=0, ge=0, description="警告数量")
    errors: List[Dict[str, str]] = Field(default_factory=list, description="错误详情列表")
    warnings: List[str] = Field(default_factory=list, description="警告信息列表")
    timestamp: datetime = Field(default_factory=datetime.now, description="验证时间")


class FieldValidationRule(BaseModel):
    """字段验证规则模式"""
    field_name: str = Field(..., description="字段名称")
    rule_type: str = Field(..., description="规则类型")
    rule_config: Dict[str, Any] = Field(default_factory=dict, description="规则配置")
    error_message: str = Field(..., description="错误消息")
    is_required: bool = Field(default=False, description="是否必填")


class CoordinateValidation(BaseModel):
    """坐标验证模式"""
    longitude: float = Field(..., ge=-180, le=180, description="经度")
    latitude: float = Field(..., ge=-90, le=90, description="纬度")
    
    @field_validator('longitude', 'latitude')
    @classmethod
    def validate_coordinate_precision(cls, v: float) -> float:
        """验证坐标精度"""
        try:
            # 检查精度（小数点后最多6位）
            decimal_places = len(str(v).split('.')[-1]) if '.' in str(v) else 0
            if decimal_places > 6:
                raise ValueError(f"坐标精度过高，小数点后最多6位，当前：{decimal_places}位")
            return v
        except Exception as e:
            raise ValueError(f"坐标验证失败：{str(e)}")
    
    @model_validator(mode='after')
    def validate_coordinate_pair(self) -> 'CoordinateValidation':
        """验证坐标对的合理性"""
        try:
            CameraValidators.validate_coordinates(self.longitude, self.latitude)
        except ValidationError as e:
            raise ValueError(e.message)
        return self


class EnumValidation(BaseModel):
    """枚举验证模式"""
    
    @classmethod
    def validate_camera_status(cls, status: str) -> bool:
        """验证摄像头状态枚举"""
        valid_statuses = [s.value for s in CameraStatus]
        return status in valid_statuses
    
    @classmethod
    def validate_stream_status(cls, status: str) -> bool:
        """验证流状态枚举"""
        valid_statuses = [s.value for s in StreamStatus]
        return status in valid_statuses


class BusinessRuleValidation(BaseModel):
    """业务规则验证模式"""
    rule_name: str = Field(..., description="规则名称")
    rule_description: str = Field(..., description="规则描述")
    validation_function: str = Field(..., description="验证函数名")
    parameters: Dict[str, Any] = Field(default_factory=dict, description="验证参数")
    severity: str = Field(default="error", description="严重级别：error, warning, info")
    
    @field_validator('severity')
    @classmethod
    def validate_severity(cls, v: str) -> str:
        """验证严重级别"""
        valid_severities = ['error', 'warning', 'info']
        if v not in valid_severities:
            raise ValueError(f"无效的严重级别：{v}，有效值：{valid_severities}")
        return v


class CameraValidationConfig(BaseModel):
    """摄像头验证配置模式"""
    enable_coordinate_validation: bool = Field(default=True, description="启用坐标验证")
    enable_name_uniqueness_check: bool = Field(default=True, description="启用名称唯一性检查")
    enable_rtsp_connectivity_test: bool = Field(default=False, description="启用RTSP连接测试")
    enable_ai_algorithm_validation: bool = Field(default=True, description="启用AI算法验证")
    coordinate_precision_limit: int = Field(default=6, ge=1, le=10, description="坐标精度限制")
    max_description_length: int = Field(default=1000, ge=100, le=5000, description="描述最大长度")
    
    # 业务规则配置
    allow_duplicate_coordinates: bool = Field(default=False, description="允许重复坐标")
    coordinate_tolerance: float = Field(default=0.0001, ge=0, le=1, description="坐标容差")
    require_location_for_outdoor: bool = Field(default=True, description="室外摄像头需要位置信息")
    
    # AI算法配置
    max_ai_algorithms_per_camera: int = Field(default=5, ge=1, le=20, description="每个摄像头最大AI算法数")
    default_confidence_threshold: float = Field(default=0.5, ge=0, le=1, description="默认置信度阈值")


class CameraDataIntegrityCheck(BaseModel):
    """摄像头数据完整性检查模式"""
    camera_id: int = Field(..., description="摄像头ID")
    check_type: str = Field(..., description="检查类型")
    check_result: bool = Field(..., description="检查结果")
    issues_found: List[str] = Field(default_factory=list, description="发现的问题")
    recommendations: List[str] = Field(default_factory=list, description="建议措施")
    check_timestamp: datetime = Field(default_factory=datetime.now, description="检查时间")
    
    @field_validator('check_type')
    @classmethod
    def validate_check_type(cls, v: str) -> str:
        """验证检查类型"""
        valid_types = [
            'coordinate_validation',
            'rtsp_connectivity',
            'ai_algorithm_compatibility',
            'data_consistency',
            'performance_metrics',
            'security_compliance'
        ]
        if v not in valid_types:
            raise ValueError(f"无效的检查类型：{v}，有效值：{valid_types}")
        return v


# Task 5.3 增强的筛选和分页模式

class PaginationMeta(BaseModel):
    """分页元数据模式"""
    current_page: int = Field(..., ge=1, description="当前页码")
    per_page: int = Field(..., ge=1, le=100, description="每页大小")
    total_items: int = Field(..., ge=0, description="总记录数")
    total_pages: int = Field(..., ge=0, description="总页数")
    has_previous: bool = Field(..., description="是否有上一页")
    has_next: bool = Field(..., description="是否有下一页")
    previous_page: Optional[int] = Field(None, description="上一页页码")
    next_page: Optional[int] = Field(None, description="下一页页码")
    start_index: int = Field(..., ge=0, description="当前页起始索引")
    end_index: int = Field(..., ge=0, description="当前页结束索引")


class SortConfig(BaseModel):
    """排序配置模式"""
    field: str = Field(..., description="排序字段")
    order: SortOrder = Field(default=SortOrder.ASC, description="排序方向")
    
    @field_validator('field')
    @classmethod
    def validate_sort_field(cls, v: str) -> str:
        """验证排序字段"""
        valid_fields = {
            'id', 'name', 'location', 'status', 'ai_enabled',
            'longitude', 'latitude', 'height', 'created_at', 'updated_at',
            'wvp_device_id', 'processing_fps', 'priority_level'
        }
        
        if v not in valid_fields:
            raise ValueError(f"无效的排序字段：{v}")
        
        return v


class SearchConfig(BaseModel):
    """搜索配置模式"""
    query: str = Field(..., min_length=1, max_length=255, description="搜索查询")
    fields: List[str] = Field(
        default=['name', 'location', 'description'],
        description="搜索字段"
    )
    case_sensitive: bool = Field(default=False, description="是否区分大小写")
    exact_match: bool = Field(default=False, description="是否精确匹配")
    
    @field_validator('fields')
    @classmethod
    def validate_search_fields(cls, v: List[str]) -> List[str]:
        """验证搜索字段"""
        valid_fields = {'name', 'location', 'description', 'wvp_device_id'}
        
        for field in v:
            if field not in valid_fields:
                raise ValueError(f"无效的搜索字段：{field}")
        
        return v


class GeographicFilter(BaseModel):
    """地理位置筛选模式"""
    bounds: Optional[Dict[str, float]] = Field(
        default=None,
        description="边界框筛选 {min_lng, max_lng, min_lat, max_lat}"
    )
    center: Optional[Dict[str, float]] = Field(
        default=None,
        description="中心点 {longitude, latitude}"
    )
    radius: Optional[float] = Field(
        default=None,
        ge=0,
        description="半径（公里）"
    )
    
    @model_validator(mode='after')
    def validate_geographic_filter(self) -> 'GeographicFilter':
        """验证地理筛选参数"""
        if self.center and self.radius is None:
            raise ValueError("使用中心点筛选时必须提供半径")
        
        if self.radius and not self.center:
            raise ValueError("使用半径筛选时必须提供中心点")
        
        if self.bounds:
            required_keys = {'min_lng', 'max_lng', 'min_lat', 'max_lat'}
            if not all(key in self.bounds for key in required_keys):
                raise ValueError(f"边界框必须包含所有键：{required_keys}")
        
        return self


class TimeRangeFilter(BaseModel):
    """时间范围筛选模式"""
    start_time: Optional[datetime] = Field(default=None, description="开始时间")
    end_time: Optional[datetime] = Field(default=None, description="结束时间")
    field: str = Field(default="created_at", description="时间字段")
    
    @field_validator('field')
    @classmethod
    def validate_time_field(cls, v: str) -> str:
        """验证时间字段"""
        valid_fields = {'created_at', 'updated_at'}
        if v not in valid_fields:
            raise ValueError(f"无效的时间字段：{v}")
        return v
    
    @model_validator(mode='after')
    def validate_time_range(self) -> 'TimeRangeFilter':
        """验证时间范围"""
        if (self.start_time and self.end_time and 
            self.start_time > self.end_time):
            raise ValueError("开始时间不能晚于结束时间")
        return self


class AdvancedCameraFilters(BaseModel):
    """高级摄像头筛选模式"""
    basic_filters: CameraFilters = Field(..., description="基础筛选条件")
    geographic_filter: Optional[GeographicFilter] = Field(
        default=None,
        description="地理位置筛选"
    )
    time_range_filter: Optional[TimeRangeFilter] = Field(
        default=None,
        description="时间范围筛选"
    )
    search_config: Optional[SearchConfig] = Field(
        default=None,
        description="搜索配置"
    )
    sort_configs: List[SortConfig] = Field(
        default_factory=lambda: [SortConfig(field="created_at", order=SortOrder.DESC)],
        description="排序配置（支持多字段排序）"
    )
    
    # 性能优化选项
    use_cache: bool = Field(default=True, description="是否使用缓存")
    cache_ttl: int = Field(default=300, ge=0, description="缓存TTL（秒）")
    
    def to_sql_conditions(self) -> Dict[str, Any]:
        """转换为SQL查询条件"""
        conditions = {}
        
        # 基础筛选条件
        basic_dict = self.basic_filters.to_dict()
        conditions.update(basic_dict)
        
        # 地理位置筛选
        if self.geographic_filter:
            if self.geographic_filter.bounds:
                conditions['geographic_bounds'] = self.geographic_filter.bounds
            elif self.geographic_filter.center and self.geographic_filter.radius:
                conditions['geographic_circle'] = {
                    'center': self.geographic_filter.center,
                    'radius': self.geographic_filter.radius
                }
        
        # 时间范围筛选
        if self.time_range_filter:
            conditions['time_range'] = {
                'field': self.time_range_filter.field,
                'start': self.time_range_filter.start_time,
                'end': self.time_range_filter.end_time
            }
        
        # 搜索条件
        if self.search_config:
            conditions['search'] = {
                'query': self.search_config.query,
                'fields': self.search_config.fields,
                'case_sensitive': self.search_config.case_sensitive,
                'exact_match': self.search_config.exact_match
            }
        
        return conditions


class CameraQueryBuilder(BaseModel):
    """摄像头查询构建器"""
    filters: AdvancedCameraFilters = Field(..., description="筛选条件")
    
    def build_query(self) -> Dict[str, Any]:
        """构建查询"""
        return {
            'conditions': self.filters.to_sql_conditions(),
            'sort': [
                {'field': sort_config.field, 'order': sort_config.order.value}
                for sort_config in self.filters.sort_configs
            ],
            'pagination': {
                'page': self.filters.basic_filters.page,
                'size': self.filters.basic_filters.size
            },
            'options': {
                'use_cache': self.filters.use_cache,
                'cache_ttl': self.filters.cache_ttl
            }
        }


class CameraAggregation(BaseModel):
    """摄像头聚合查询模式"""
    group_by: List[str] = Field(..., description="分组字段")
    aggregations: Dict[str, str] = Field(..., description="聚合函数")
    filters: Optional[CameraFilters] = Field(default=None, description="筛选条件")
    
    @field_validator('group_by')
    @classmethod
    def validate_group_fields(cls, v: List[str]) -> List[str]:
        """验证分组字段"""
        valid_fields = {
            'status', 'ai_enabled', 'location', 'wvp_device_id',
            'created_date', 'updated_date'
        }
        
        for field in v:
            if field not in valid_fields:
                raise ValueError(f"无效的分组字段：{field}")
        
        return v
    
    @field_validator('aggregations')
    @classmethod
    def validate_aggregations(cls, v: Dict[str, str]) -> Dict[str, str]:
        """验证聚合函数"""
        valid_functions = {'count', 'sum', 'avg', 'min', 'max'}
        
        for field, func in v.items():
            if func not in valid_functions:
                raise ValueError(f"无效的聚合函数：{func}")
        
        return v


class CameraExportConfig(BaseModel):
    """摄像头导出配置模式"""
    filters: CameraFilters = Field(..., description="导出筛选条件")
    format: str = Field(default="csv", description="导出格式")
    fields: Optional[List[str]] = Field(default=None, description="导出字段")
    include_metadata: bool = Field(default=True, description="是否包含元数据")
    
    @field_validator('format')
    @classmethod
    def validate_export_format(cls, v: str) -> str:
        """验证导出格式"""
        valid_formats = {'csv', 'xlsx', 'json', 'xml'}
        if v not in valid_formats:
            raise ValueError(f"无效的导出格式：{v}")
        return v